<?php

/**
 * Description of NewApartamenteForm
 *
 * @author verminu
 */
class NewApartamentListForm extends BaseScaraForm
{
  // structura form-ului este asemanatoare cu cea de la EmptyBlocListForm

  const NAME = 'apartamente';
  const WRAPPER_NAME = 'list';

  protected $responseData = array();

  public function getResponseData()
  {
    return $this->responseData;
  }

  public function configure()
  {
    // formularul va contine doar ID-ul scarii (camp ascuns)
    $this->useFields();

    // setez formatul atributului name al field-urilor
    $this->getWidgetSchema()->setNameFormat(self::NAME.'[%s]');

    // numarul apartamentelor ce pot fi inregistrate la un moment dat este limitat
    $countApartamente = min(array($this->getObject()->getRemainingAps(), sfConfig::get('mod_apartamente_max_new_aps')));

    // numarul apartamentelor se genereaza automat
    $startNumber = $this->getObject()->getNextApartamentNumber();

    // creez sub-form-uri pe care le atasez formularului principal
    $wrapperForm = new sfForm();
    for ($i = 0; $i < $countApartamente; $i++)
    {
      $apartamentForm = new NewApartamentForm(null, array('scara' => $this->getObject()));
      $apartamentForm->setDefault('number', $startNumber++);

      $wrapperForm->embedForm($i, $apartamentForm);
    }
    $this->embedForm(self::WRAPPER_NAME, $wrapperForm);

    // setez un pre-validator
    $this->mergePreValidator(new NewApartamentListPreValidator());

    // setez un post-validator
    $this->mergePostValidator(new NewApartamentListPostValidator());

  }

  /**
   * Metoda se rescrie pt a ignora apartamentele care nu sunt completate
   *
   * @param array $taintedValues
   * @param array $taintedFiles
   * @return array
   */
  public function bindAndSave(array $taintedValues = null, array $taintedFiles = null)
  {
    // inregistrarea apartamentelor are loc doar daca REMAINING_APS > 0
    if ($this->getObject()->getRemainingAps() <= 0)
    {
      // se incearca adaugarea fortata a unor apartamente;
      // in acest caz se impune un reincarcarea paginii
      $this->responseData['refresh'] = true;

      return false;
    }

    $remainingAps = $this->getObject()->getRemainingAps();
    $count = 0;
    $usedKeys = array();

    foreach ($taintedValues[self::WRAPPER_NAME] as $key => $apartament)
    {
      $empty = true;
      foreach ($apartament as $aKey => $aValues)
      {
        if (!is_array($aValues))
        {
          $aValues = array($aValues);
        }

        foreach ($aValues as $aValue)
        {
          if (strlen(trim($aValue)) > 0)
          {
            $empty = false;
            break;
          }
        }

        if (!$empty)
        {
          break;
        }
      }

      if (!$empty)
      {
        // se contorizeaza nr apartamentelor ce vor fi inregistrate;
        // numarul acestora trebuie sa fie mai mic sau egal cu REMAINING_APS
        $count++;
        if ($count > $remainingAps)
        {
          // se forteaza stergerea apartamentelor care sunt in plus
          $empty = true;
        }
      }

      if (!$empty)
      {
        $usedKeys[$key] = true;
      }

      if ($empty)
      {
        // ignor intreaga linie
        unset($taintedValues[self::WRAPPER_NAME][$key]);
      }
    }

    foreach ($this->embeddedForms[self::WRAPPER_NAME] as $key => $ef)
    {
      // pastrez doar sub-form-urile care sunt completate
      if (empty($usedKeys[$key]))
      {
        Forms::delete($this, array(self::WRAPPER_NAME, $key));
      }
    }

    return parent::bindAndSave($taintedValues, $taintedFiles);
  }

  protected function doUpdateObject($values)
  {
    parent::doUpdateObject($values);

    // actualizez REMAINING_APS
    $val = $this->getObject()->getRemainingAps();
    $this->getObject()->setRemainingAps(max(array($val - count($this[self::WRAPPER_NAME], 0))));
  }

  protected function doSave($con = null)
  {
    parent::doSave($con);

    // trimit ca raspuns: nr total de apartamente, daca scara este incompleta
    $this->responseData['total'] = $this->getObject()->getApartamenteCount();
    $this->responseData['incomplete'] = $this->getObject()->isIncomplete();
  }

}
